home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / FIELD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.4 KB  |  259 lines

  1.  
  2. /* field.c - by Tom McReynolds, SGI */
  3.  
  4. /* Using the accumulation buffer for depth of field (camera focus blur). */
  5.  
  6. #include <GL/glut.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9.  
  10. const GLdouble FRUSTDIM = 100.f;
  11. const GLdouble FRUSTNEAR = 320.f;
  12. const GLdouble FRUSTFAR = 660.f;
  13.  
  14. /*
  15. ** Create a single component texture map
  16. */
  17. GLfloat *make_texture(int maxs, int maxt)
  18. {
  19.     int s, t;
  20.     static GLfloat *texture;
  21.  
  22.     texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
  23.     for(t = 0; t < maxt; t++) {
  24.         for(s = 0; s < maxs; s++) {
  25.             texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1);
  26.         }
  27.     }
  28.     return texture;
  29. }
  30.  
  31. enum {SPHERE = 1, CONE};
  32.  
  33. void
  34. render(void)
  35. {
  36.     /* material properties for objects in scene */
  37.     static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f};
  38.  
  39.     glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  40.  
  41.     /*
  42.     ** Note: wall verticies are ordered so they are all front facing
  43.     ** this lets me do back face culling to speed things up.
  44.     */
  45.  
  46.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
  47.  
  48.     /* floor */
  49.     /* make the floor textured */
  50.     glEnable(GL_TEXTURE_2D);
  51.  
  52.     /*
  53.     ** Since we want to turn texturing on for floor only, we have to
  54.     ** make floor a separate glBegin()/glEnd() sequence. You can't
  55.     ** turn texturing on and off between begin and end calls
  56.     */
  57.     glBegin(GL_QUADS);
  58.     glNormal3f(0.f, 1.f, 0.f);
  59.     glTexCoord2i(0, 0);
  60.     glVertex3f(-100.f, -100.f, -320.f);
  61.     glTexCoord2i(1, 0);
  62.     glVertex3f( 100.f, -100.f, -320.f);
  63.     glTexCoord2i(1, 1);
  64.     glVertex3f( 100.f, -100.f, -640.f);
  65.     glTexCoord2i(0, 1);
  66.     glVertex3f(-100.f, -100.f, -640.f);
  67.     glEnd();
  68.  
  69.     glDisable(GL_TEXTURE_2D);
  70.  
  71.     /* walls */
  72.  
  73.     glBegin(GL_QUADS);
  74.     /* left wall */
  75.     glNormal3f(1.f, 0.f, 0.f);
  76.     glVertex3f(-100.f, -100.f, -320.f);
  77.     glVertex3f(-100.f, -100.f, -640.f);
  78.     glVertex3f(-100.f,  100.f, -640.f);
  79.     glVertex3f(-100.f,  100.f, -320.f);
  80.  
  81.     /* right wall */
  82.     glNormal3f(-1.f, 0.f, 0.f);
  83.     glVertex3f( 100.f, -100.f, -320.f);
  84.     glVertex3f( 100.f,  100.f, -320.f);
  85.     glVertex3f( 100.f,  100.f, -640.f);
  86.     glVertex3f( 100.f, -100.f, -640.f);
  87.  
  88.     /* ceiling */
  89.     glNormal3f(0.f, -1.f, 0.f);
  90.     glVertex3f(-100.f,  100.f, -320.f);
  91.     glVertex3f(-100.f,  100.f, -640.f);
  92.     glVertex3f( 100.f,  100.f, -640.f);
  93.     glVertex3f( 100.f,  100.f, -320.f);
  94.  
  95.     /* back wall */
  96.     glNormal3f(0.f, 0.f, 1.f);
  97.     glVertex3f(-100.f, -100.f, -640.f);
  98.     glVertex3f( 100.f, -100.f, -640.f);
  99.     glVertex3f( 100.f,  100.f, -640.f);
  100.     glVertex3f(-100.f,  100.f, -640.f);
  101.     glEnd();
  102.  
  103.  
  104.     glPushMatrix();
  105.     glTranslatef(-80.f, -60.f, -420.f);
  106.     glCallList(SPHERE);
  107.     glPopMatrix();
  108.  
  109.  
  110.     glPushMatrix();
  111.     glTranslatef(-20.f, -80.f, -600.f);
  112.     glCallList(CONE);
  113.     glPopMatrix();
  114.  
  115.     if(glGetError()) /* to catch programming errors; should never happen */
  116.        printf("Oops! I screwed up my OpenGL calls somewhere\n");
  117.  
  118.     glFlush(); /* high end machines may need this */
  119. }
  120.  
  121. enum {NONE, FIELD};
  122.  
  123. int rendermode = NONE;
  124.  
  125. void
  126. menu(int selection)
  127. {
  128.   rendermode = selection;
  129.   glutPostRedisplay();
  130. }
  131.  
  132. GLdouble focus = 420.;
  133.  
  134. /* Called when window needs to be redrawn */
  135. void redraw(void)
  136. {
  137.     int i, j;
  138.     int min, max;
  139.     int count;
  140.     GLfloat scale, dx, dy;
  141.  
  142.     switch(rendermode) {
  143.     case NONE:
  144.       glLoadIdentity();
  145.       glMatrixMode(GL_PROJECTION);
  146.       glLoadIdentity();
  147.       glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); 
  148.       glMatrixMode(GL_MODELVIEW);
  149.       render();
  150.       break;
  151.     case FIELD:
  152.       min = -2;
  153.       max = -min + 1;
  154.       count = -2 * min + 1;
  155.       count *= count;
  156.  
  157.       scale = 2.f;
  158.  
  159.       glClear(GL_ACCUM_BUFFER_BIT);
  160.  
  161.       for(j = min; j < max; j++) {
  162.         for(i = min; i < max; i++) {
  163.           dx = scale * i * FRUSTNEAR/focus;
  164.           dy = scale * j * FRUSTNEAR/focus;
  165.           glMatrixMode(GL_PROJECTION);
  166.           glLoadIdentity();
  167.           glFrustum(-FRUSTDIM + dx, 
  168.                     FRUSTDIM + dx, 
  169.                     -FRUSTDIM + dy, 
  170.                     FRUSTDIM + dy, 
  171.                     FRUSTNEAR,
  172.                     FRUSTFAR); 
  173.           glMatrixMode(GL_MODELVIEW);
  174.           glLoadIdentity();
  175.           glTranslatef(scale * i, scale * j, 0.f);
  176.           render();
  177.           glAccum(GL_ACCUM, 1.f/count);
  178.         }
  179.       } 
  180.       glAccum(GL_RETURN, 1.f);
  181.     break;
  182.     }
  183.  
  184.     glutSwapBuffers();
  185. }
  186.  
  187. /* ARGSUSED1 */
  188. void key(unsigned char key, int x, int y)
  189. {
  190.     if(key == '\033')
  191.         exit(0);
  192. }
  193.  
  194.  
  195. const int TEXDIM = 256;
  196. /* Parse arguments, and set up interface between OpenGL and window system */
  197. int
  198. main(int argc, char *argv[])
  199. {
  200.     GLfloat *tex;
  201.     static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f};
  202.     static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f};
  203.     static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f};
  204.     GLUquadricObj *sphere, *cone, *base;
  205.  
  206.     glutInit(&argc, argv);
  207.     glutInitWindowSize(512, 512);
  208.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE);
  209.     (void)glutCreateWindow("depth of field");
  210.     glutDisplayFunc(redraw);
  211.     glutKeyboardFunc(key);
  212.  
  213.     glutCreateMenu(menu);
  214.     glutAddMenuEntry("Normal", NONE);
  215.     glutAddMenuEntry("Depth of Field", FIELD);
  216.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  217.  
  218.     /* turn on features */
  219.     glEnable(GL_DEPTH_TEST);
  220.     glEnable(GL_LIGHTING);
  221.     glEnable(GL_LIGHT0);
  222.  
  223.     /* place light 0 in the right place */
  224.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  225.  
  226.     /* remove back faces to speed things up */
  227.     glCullFace(GL_BACK);
  228.  
  229.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  230.  
  231.     glNewList(SPHERE, GL_COMPILE);
  232.     /* make display lists for sphere and cone; for efficiency */
  233.     sphere = gluNewQuadric();
  234.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
  235.     gluSphere(sphere, 20.f, 20, 20);
  236.     gluDeleteQuadric(sphere);
  237.     glEndList();
  238.  
  239.     glNewList(CONE, GL_COMPILE);
  240.     cone = gluNewQuadric();
  241.     base = gluNewQuadric();
  242.     glRotatef(-90.f, 1.f, 0.f, 0.f);
  243.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  244.     gluDisk(base, 0., 20., 20, 1);
  245.     gluCylinder(cone, 20., 0., 60., 20, 20);
  246.     gluDeleteQuadric(cone);
  247.     gluDeleteQuadric(base);
  248.     glEndList();
  249.  
  250.     /* load pattern for current 2d texture */
  251.     tex = make_texture(TEXDIM, TEXDIM);
  252.     glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex);
  253.     free(tex);
  254.  
  255.     glutMainLoop();
  256.     return 0;             /* ANSI C requires main to return int. */
  257. }
  258.  
  259.